package com.jerome.rmi.util;

import java.util.List;

/**
 * Math tools
 * @author jerome
 * @date 2023/7/28
 */
public class MathUtil {
    /**
     * get max value
     * @param numbers datasource
     * @author jerome
     * @date 2023/7/28 17:28
     */
    public static int findMax(List<Integer> numbers) {
        checkList(numbers);
        int result = numbers.get(0);
        for (Integer num : numbers) {
            result = result > num ? result : num;
        }
        return result;
    }
    /**
     * get min value
     * @param numbers datasource
     * @author jerome
     * @date 2023/7/28 17:28
     */
    public static int findMin(List<Integer> numbers) {
        checkList(numbers);
        int result = numbers.get(0);
        for (Integer num : numbers) {
            result = result < num ? result : num;
        }
        return result;
    }
    /**
     * Euclidean algorithm
     * Find the greatest common divisor of two numbers
     * link: https://www.cuemath.com/numbers/greatest-common-divisor-gcd/
     * @param a data a
     * @param b data b
     * @author jerome
     * @date 2023/7/28 17:31
     */
    private static int findGCD(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }

    /**
     * Find the least common multiple of two numbers
     * @param a data a
     * @param b data b
     * @author jerome
     * @date 2023/7/28 17:32
     */
    private static int findLCM(int a, int b) {
        return a * b / findGCD(a, b);
    }

    /**
     * Find the greatest common divisor of an integer List
     * @param numbers datasource
     * @author jerome
     * @date 2023/7/28 17:31
     */
    public static int findGCD(List<Integer> numbers) {
        checkList(numbers);

        int result = numbers.get(0);
        for (int i = 1; i < numbers.size(); i++) {
            result = findGCD(result, numbers.get(i));
        }
        return result;
    }

    /**
     * Find the least common multiple of an integer List
     * @param numbers datasource
     * @author jerome
     * @date 2023/7/28 17:29
     */
    public static int findLCM(List<Integer> numbers) {
        checkList(numbers);

        int result = numbers.get(0);
        for (int i = 1; i < numbers.size(); i++) {
            result = findLCM(result, numbers.get(i));
        }
        return result;
    }
    /**
     * Restricted data source cannot be empty
     * @param numbers datasource
     * @author jerome
     * @date 2023/7/28 17:30
     * @throws IllegalArgumentException List is empty or null
     */
    private static void checkList(List<Integer> numbers) throws IllegalArgumentException{
        if (numbers == null || numbers.isEmpty()) {
            throw new IllegalArgumentException("List is empty or null.");
        }
    }
}
